package cn.v2tila.rsosa.management.shiro;

import cn.v2tila.rsosa.management.entity.MgtUserEntity;
import cn.v2tila.rsosa.management.service.MgtUserService;
import cn.v2tila.rsosa.management.service.serviceImpl.UserServiceImpl;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.codec.digest.DigestUtils;

/**
 * ShiroRealm
 *
 * @author v2tila on 20:16 2019/2/5
 */
@Service
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private MgtUserService mgtUserService;

    private static final Logger logger = LoggerFactory
            .getLogger(UserServiceImpl.class);
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.debug("授予角色和权限");
        // 添加权限 和 角色信息
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 获取当前登陆用户
        Subject subject = SecurityUtils.getSubject();
        MgtUserEntity user = (MgtUserEntity) subject.getPrincipal();
        // 超级管理员，添加所有角色、添加所有权限
        authorizationInfo.addRole("*");
        authorizationInfo.addStringPermission("*");
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        logger.info("用户登录认证：验证当前Subject时获取到token为：" + ReflectionToStringBuilder
                .toString(token, ToStringStyle.MULTI_LINE_STYLE));
        String username = token.getUsername();
        MgtUserEntity mgtUserEntity = mgtUserService.findByUsername(username);
        logger.debug("用户登录认证！用户信息user：" + mgtUserEntity);
        if (mgtUserEntity == null) {
            // 用户不存在
            return null;
        } else {
            // 密码存在
            // 第一个参数 ，登陆后，需要在session保存数据
            // 第二个参数，查询到密码(加密规则要和自定义的HashedCredentialsMatcher中的HashAlgorithmName散列算法一致)
            // 第三个参数 ，realm名字
            return new SimpleAuthenticationInfo(mgtUserEntity, DigestUtils.md5Hex(mgtUserEntity.getPassword()),
                    getName());
        }

    }
}
